#include<bits/stdc++.h>
using namespace std;

int T, n, m, L, V, ans1, ans2;
int d[100005], v[100005], a[100005], p[100005];
int exist[1000006];
struct region{
    int l, r;
}rg[100005];

struct sgm_tree{
    int l, r;
    int dat;
}t[4000006];

void build(int p, int l, int r){
    if(l == r){
        t[p].l = l;
        t[p].r = r;
        t[p].dat = exist[l];
        return;
    }
    int mid = (l + r) / 2;
    t[p].l = l;
    t[p].r = r;
    build(p * 2, l, mid);
    build(p * 2 + 1, mid + 1, r);
    t[p].dat = t[p * 2].dat + t[p * 2 + 1].dat;
}

int ask(int p, int l, int r){
    if(l == -1 and r == -1)
        return 0;
    if(l <= t[p].l and t[p].r <= r)
        return t[p].dat;
    int res = 0;
    int mid = (t[p].l + t[p].r) / 2;
    if(l <= mid){
        res += ask(p * 2, l, r);
    }
    if(mid < r){
        res += ask(p * 2 + 1, l, r);
    }
    return res;
}

int _count(int x){
    int cnt = 0;
    for(; x; x -= x&(-x)) cnt++;
    return cnt;
}
int main(){
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    cin >> T;
    while(T--){
        cin >> n >> m >> L >> V;
        memset(rg, -1, sizeof(rg));
        memset(t, 0, sizeof(t));
        memset(exist, 0, sizeof(exist));
        ans1 = 0;
        ans2 = 0;
        for(int i = 1; i <= n; i++){
            cin >> d[i] >> v[i] >> a[i];
            if(a[i] >= 0 and v[i] > V){//already exceed
                rg[i].l = d[i];
                rg[i].r = L;
            }
            else if(a[i] <= 0 and v[i] <= V){//never exceed
                continue;
            }
            else if(a[i] < 0 and v[i] > V){
                rg[i].l = d[i];
                double delta = (v[i] * v[i] - V * V) / 2 / (-a[i]);
                if(d[i] + delta > L)
                    rg[i].r = L;
                else{
                    if(d[i] + delta > (int)(d[i] + delta))
                        rg[i].r = (int)(d[i] + delta);
                    else
                        rg[i].r = max(d[i], (int)(d[i] + delta) - 1);
                }
            }
            else{//a[i] > 0 and v[i] <= V
                double delta = (V * V - v[i] * v[i]) / 2 / a[i];
                if(d[i] + delta > L)
                    continue;
                else{
                    rg[i].l = min(L, (int)(d[i] + delta) + 1);
                    rg[i].r = L;
                }
            }
        }
        for(int i = 1; i <= m; i++){
            cin >> p[i];
            exist[p[i]] = 1;
        }
        build(1, 1, L);
        for(int i = 1; i <= n; i++){
            if(ask(1, rg[i].l, rg[i].r))
                ans1++;
        }
        cout << ans1 << " ";

        int mini = 0x3fffffff;
        for(int state = 0; state < 1<<(m+1); state++){
                int temp = 0;
            for(int i = 0; i < m; i++){
                bool tmp = state & (1<<i);
                exist[p[i+1]] = 0;
            }
            build(1, 1, n);
            for(int i = 1; i <= n; i++){
                if(ask(1, rg[i].l, rg[i].r))
                    temp++;
            }
        if(temp == ans1)
            mini = min(mini, _count(state));
        }
        ans2 = n - mini;
        cout << ans2 << endl;
    }
    return 0;
}
